package com.peng.herostory;

import com.google.protobuf.GeneratedMessageV3;
import com.peng.herostory.cmdhanlder.CmdHandlerFactory;
import com.peng.herostory.cmdhanlder.ICmdHandler;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 游戏服务器中，为了降低 不知道是由于业务还是多线程导致的问题的复杂度，通常都将业务放在单线程中进行处理
 * 因为是在内存中，所以其实是比较快的。。。
 */
@Slf4j
public final class MainThreadProcessor {
    private static final MainThreadProcessor instance = new MainThreadProcessor();
    private final ExecutorService executor = Executors.newSingleThreadExecutor(runnable -> {
        Thread thread = new Thread(runnable);
        thread.setName("MainThread");
        return thread;
    });

    private MainThreadProcessor() {

    }

    public static MainThreadProcessor getInstance() {
        return instance;
    }

    public void process(ChannelHandlerContext ctx, GeneratedMessageV3 msg) {
        if (ctx == null || msg == null) {
            return;
        }
        executor.submit(() -> {
            log.info("{},收到客户端消息, msgClazz = " + msg.getClass().getName() + ", msg = " + msg, Thread.currentThread().getName());
            ICmdHandler<? extends GeneratedMessageV3> cmdHandler = CmdHandlerFactory.createHandler(msg.getClass());
            if (cmdHandler != null) {
                try {
                    cmdHandler.handle(ctx, cast(msg));
                } catch (Exception e) {
                    log.error("{1}", e);

                }
            }
        });

    }

    public void process(Runnable runnable) {
        if (runnable == null) {
            return;
        }
        executor.submit(runnable);
    }

    private <Cmd extends GeneratedMessageV3> Cmd cast(Object msg) {
        if (msg == null) {
            return null;
        }
        return (Cmd) msg;
    }


}
